package org.nlp2rdf.navigator.client;

import java.util.ArrayList;
import java.util.List;

import org.nlp2rdf.navigator.client.common.ClassificationResultDTO;
import org.nlp2rdf.navigator.client.common.ConceptDTO;
import org.nlp2rdf.navigator.client.common.LearnedConceptDTO;
import org.nlp2rdf.navigator.client.functionality.ConceptWidget;
import org.nlp2rdf.navigator.client.functionality.TitleWidget;
import org.nlp2rdf.navigator.client.util.ConceptDTOHelper;
import org.nlp2rdf.navigator.client.util.PopupHelper;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class LearnedConceptWidget extends Composite {

	private static int DEFAULT_LIMIT = 50;
	private static int DEFAULT_OFFSET = 0;

	private Application app;

	// four actions are possible
	private final Anchor specificAnchor = new Anchor("more specific");
	private final Anchor generalAnchor = new Anchor("more general");
	private final Button retrieveInstance = new Button("Matching");

	private LearnedConceptDTO currentLearnedConcept;
	private RefinementSynchronizer mySynchronizer;
	private TitleWidget titleWidget = new TitleWidget("Learned Concept");

	final HorizontalPanel displayConcept = new HorizontalPanel();

	public LearnedConceptWidget(final Application app) {
		this.app = app;
		VerticalPanel mainPanel = new VerticalPanel();
		// final int limit = 50;
		// final int offset = 0;
		displayConcept.add(new HTML("<span style='font-style: italic;' >Nothing learned </span>"));
		displayConcept.setWidth("100%");

		mainPanel.add(titleWidget);
		mainPanel.add(displayConcept);
		mainPanel.addStyleName("module-border");
		mainPanel.setWidth("95%");
		mainPanel.addStyleName("greyed");

		retrieveInstance.setWidth("100%");
		retrieveInstance.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				retrieveInstance.setEnabled(false);
				app.getWorkerService().classify(currentLearnedConcept.getKbSyntaxString(), DEFAULT_LIMIT,
						DEFAULT_OFFSET, new AsyncCallback<ClassificationResultDTO>() {
							public void onFailure(Throwable arg0) {
								app.reportError(arg0);
								retrieveInstance.setEnabled(true);
							}

							public void onSuccess(ClassificationResultDTO rrdto) {
								app.displayClassificationResult(rrdto);
								retrieveInstance.setEnabled(true);
							}
						});

			}
		});

		initSpecializeNGeneralzeWidgets();
		initWidget(mainPanel);

		// final HorizontalPanel displayConcept = new HorizontalPanel();
		// HorizontalPanel displayAccuracy = new HorizontalPanel();
		//
		// // This panel holds all things for refining the concept
		// VerticalPanel learnedMetaPanel = new VerticalPanel();
		// learned.setWidth("100%");
		// learnedMetaPanel.setWidth("100px");
		// learnedMetaPanel.addStyleName("padding-left:10px");
		//
		// mainPanel.add(displayConcept);
		//
		// Label title = new Label("Learned Concept");
		// title.addStyleName("module-title");
		// displayConcept.add(title);
		// learnedPanel = new HTML();
		//
		// learned.add(learnedPanel);
		//
		// displayAccuracy.add(new Label("Acc.:"));
		// accuracy = new Label("");
		// displayAccuracy.add(accuracy);
		// learnedMetaPanel.add(displayAccuracy);
		//
		// mainPanel.add(learned);
		//
		// // some dummy items
		//
		// // displayConcept.add(specLabel);
		//
		// learnedMetaPanel.add(specLabel);
		// learnedMetaPanel.add(genLabel);
		// learned.add(learnedMetaPanel);
		//
		// learned.setCellHorizontalAlignment(learnedMetaPanel,
		// HasHorizontalAlignment.ALIGN_RIGHT);
		//
		// searchInstances = new Button("Matching");
		//		
		//
		// toSession = new Button("Save to export");
		//		
		//
		// HorizontalPanel buttonPanel = new HorizontalPanel();
		// buttonPanel.setWidth("100%");
		// buttonPanel.add(searchInstances);
		// buttonPanel.setCellHorizontalAlignment(searchInstances,
		// HasHorizontalAlignment.ALIGN_LEFT);
		// buttonPanel.add(toSession);
		// buttonPanel.setCellHorizontalAlignment(toSession,
		// HasHorizontalAlignment.ALIGN_RIGHT);
		// mainPanel.add(buttonPanel);
		//
		//		

	}

	private void initSpecializeNGeneralzeWidgets() {

		final PopupPanel pp = new PopupPanel();

		mySynchronizer = new RefinementSynchronizer(pp);

		specificAnchor.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				app.getWorkerService().specialise(currentLearnedConcept.getKbSyntaxString(),
						new AsyncCallback<List<LearnedConceptDTO>>() {
							public void onFailure(Throwable arg0) {
								app.reportError(arg0);
							}

							public void onSuccess(List<LearnedConceptDTO> results) {
								mySynchronizer.set(results);
							}
						});
				pp.showRelativeTo(specificAnchor);
				pp.show();

			}
		});

		generalAnchor.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				app.getWorkerService().generalise(currentLearnedConcept.getKbSyntaxString(),
						new AsyncCallback<List<LearnedConceptDTO>>() {
							public void onFailure(Throwable arg0) {
								app.reportError(arg0);
							}

							public void onSuccess(List<LearnedConceptDTO> results) {
								mySynchronizer.set(results);
							}
						});

				pp.showRelativeTo(generalAnchor);
				pp.show();

			}
		});
	}

	public void update(LearnedConceptDTO conceptDTO) {
		this.currentLearnedConcept = conceptDTO;
		ConceptWidget w = new ConceptWidget(conceptDTO, app);
		//TODO not nice code
		w.generalAction = generalAnchor;
		w.specializeAction=specificAnchor;
		w.match = retrieveInstance;

		w.displayAsLearnedConcept();


		// this hides a bug in the backend
		specificAnchor.setVisible(app.learningWasExecutedOnce);
		generalAnchor.setVisible(app.learningWasExecutedOnce);

		displayConcept.clear();
		displayConcept.add(w);

	}

	public LearnedConceptDTO getLearningResult() {
		return currentLearnedConcept;
	}

	private class RefinementSynchronizer {
		final private List<LearnedConceptDTO> refinements = new ArrayList<LearnedConceptDTO>();
		final private ListBox lb;

		public RefinementSynchronizer(final PopupPanel pp) {
			lb = new ListBox();
			pp.setWidget(lb);
			pp.setAutoHideEnabled(true);
			lb.setVisibleItemCount(10);
			lb.addClickHandler(new ClickHandler() {
				public void onClick(ClickEvent arg0) {
					update(refinements.get(lb.getSelectedIndex()));
					pp.hide();
				}
			});
		}

		private void clear() {
			refinements.clear();
			lb.clear();
		}

		public void set(List<LearnedConceptDTO> results) {
			clear();
			refinements.addAll(results);
			for (ConceptDTO result : results) {
				lb.addItem(ConceptDTOHelper.getMOSNoHTML(result));
				// lb.addItem(LearningResultHelper.getNoHTML(result));
			}
		}
	}

}